package com.araaya.eslimsmobile.gps;

import java.io.File;
import java.io.StringWriter;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.StringTokenizer;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import android.util.Log;

public class MobileKmlWriter {

	private long referenceNo;

	/*
	 * public static void main(String[] args) { // TODO Auto-generated method
	 * stub MobileKmlWriter mobileKmlWriter = new MobileKmlWriter(); File ff =
	 * new File("test1.kml"); // File newFile=new File("samra.kml"); //
	 * newFile=kmlWriter.writeKmlFile(ff); mobileKmlWriter.writeKmlFile(ff);
	 * 
	 * }
	 */

	// Write KML
	public String writeKmlFile(File file,
			ArrayList<HashMap<String, String>> points) {
		// File createFile = null;
		String writerString = null;
		try {

			DocumentBuilderFactory docFactory = DocumentBuilderFactory
					.newInstance();
			DocumentBuilder docBuilder = docFactory.newDocumentBuilder();

			// root elements
			Document doc = docBuilder.newDocument();
			Element rootElement = doc.createElement("kml");
			doc.appendChild(rootElement);

			// placemark elements
			Element placemark = doc.createElement("Placemark");
			rootElement.appendChild(placemark);

			// name elements
			Element name = doc.createElement("name");
			name.appendChild(doc.createTextNode("Land"));
			placemark.appendChild(name);

			// Polygon elements
			Element polygon = doc.createElement("Polygon");
			placemark.appendChild(polygon);

			// extrude elements
			Element extrude = doc.createElement("extrude");
			extrude.appendChild(doc.createTextNode("1"));
			polygon.appendChild(extrude);

			// altitudeMode elements
			Element altitudeMode = doc.createElement("altitudeMode");
			altitudeMode.appendChild(doc.createTextNode("relativeToGround"));
			polygon.appendChild(altitudeMode);

			// outerBoundaryIs elements
			Element outerBoundaryIs = doc.createElement("outerBoundaryIs");
			polygon.appendChild(outerBoundaryIs);

			// LinearRing elements
			Element LinearRing = doc.createElement("LinearRing");
			outerBoundaryIs.appendChild(LinearRing);
			
			/*Element LinearRing = doc.createElement("LineString");
			outerBoundaryIs.appendChild(LinearRing);*/
			
			

			// coordinates elements
			Element coordinates = doc.createElement("coordinates");
			// ReadXMLFile readXMLFile = new ReadXMLFile();

			String resultCoordinates = getCoordinateValue(points);
			String resultPoint = "";
			if (resultCoordinates != null) {
				resultPoint = getMiddlePoint(resultCoordinates);
				if (resultCoordinates.length() > 0) {
					coordinates.appendChild(doc
							.createTextNode(resultCoordinates));

				}
				System.out.println("cordinate==" + resultCoordinates);
				System.out.println("Middle==" + resultPoint);
			}

			LinearRing.appendChild(coordinates);

			// Add a point
			// placemark elements
			Element placemark2 = doc.createElement("Placemark");
			rootElement.appendChild(placemark2);

			// name elements
			Element name2 = doc.createElement("name");
			name2.appendChild(doc.createTextNode("" + getReferenceNo()));
			placemark2.appendChild(name2);

			// description elements
			Element description = doc.createElement("description");
			description.appendChild(doc.createTextNode("Middle of the Land"));
			placemark2.appendChild(description);

			// Point elements
			Element Point = doc.createElement("Point");
			placemark2.appendChild(Point);

			// coordinates elements to point
			Element coordinatesPoint = doc.createElement("coordinates");
			// String resultPoint = getMiddlePoint(resultCoordinates);

			if (resultCoordinates.length() > 0) {
				coordinatesPoint.appendChild(doc.createTextNode(resultPoint));
			}

			Point.appendChild(coordinatesPoint);

			// referenceNo elements
			Element referenceNoEle = doc.createElement("referenceNo");
			if (getReferenceNo() != 0) {
				referenceNoEle.appendChild(doc.createTextNode(""
						+ getReferenceNo()));
			}
			Point.appendChild(referenceNoEle);

			// xml to string
			DOMSource domSource = new DOMSource(doc);
			StringWriter writer = new StringWriter();
			StreamResult result = new StreamResult(writer);
			TransformerFactory tf = TransformerFactory.newInstance();
			Transformer transformer = tf.newTransformer();
			transformer.transform(domSource, result);
			writerString = writer.toString();

			Log.d("KmlWriter", "xml to String is success");

		} catch (ParserConfigurationException pce) {
			writerString = null;
			Log.d("ParserConfigurationException", pce.getMessage());

		} catch (TransformerException tfe) {
			writerString = null;
			Log.d("TransformerException", tfe.getMessage());
		}

		return writerString;
	}

	// Read KML
	private String getCoordinateValue(ArrayList<HashMap<String, String>> points) {
		// String result =
		// "79.91896045948988,6.904406257414117,0.0 79.91900002207285,6.904426893787414,0.0 79.91905098404413,6.904426228097955,0.0 79.91910194601542,6.904406257414117,0.0 79.91913212086683,6.904368313112464,0.0 79.91920722271925,6.904310398119886,0.0 79.91917302455431,6.904293090189685,0.0 79.91917637731558,6.904247823292332,0.0 79.9191629662705,6.904195233803211,0.0 79.91909993435866,6.90418924259522,0.0 79.9190617128802,6.90416794052174,0.0 79.91901276256567,6.904197896562293,0.0 79.91897856440073,6.904289761741501,0.0";
		// String result
		// ="10.0000000000,5.0000000000,2.1 10.0000000000,5.0000000000,2.1 10.0000000000,5.0000000000,2.1 ";
		String result = "";
		try {
			result = setCoordinateValue(points);

		} catch (Exception e) {
			result = null;
			Log.d("Exception KmlWriter", e.getMessage());

		}
		return result;
	}

	// set The cordinate value
	private String setCoordinateValue(ArrayList<HashMap<String, String>> points) {
		String cordinate = "";
		HashMap<String, String> map = new HashMap<String, String>();
		for (int i = 0; i < points.size(); i++) {
			String lat, lon, alt = "";
			map = points.get(i);
			lon = map.get("lon");
			lat = map.get("lat");
			alt = map.get("alt");

			cordinate = cordinate + lon + "," + lat + "," + alt + " ";

		}

		return cordinate;
	}

	// get midPoint
	public String getMiddlePoint(String point) {
		String resultMiddle = "";
		try {

			StringTokenizer stringTokenizer = new StringTokenizer(point);

			double array[][] = new double[stringTokenizer.countTokens()][3];
			int arrayCount = 0;
			int tokenCount = stringTokenizer.countTokens();
			double lat = 0;
			double lon = 0;
			float alt = 0;
			while (stringTokenizer.hasMoreTokens()) {
				String firstToken = stringTokenizer.nextToken();
				// System.out.println(firstToken);

				StringTokenizer stringTokenizer2 = new StringTokenizer(
						firstToken, ",");
				/*
				 * System.out.println("The total no. of tokens   generated2 :  "
				 * + stringTokenizer2.countTokens());
				 */
				while (stringTokenizer2.hasMoreTokens()) {
					int col = arrayCount % 3;
					int row = arrayCount / 3;
					/*
					 * System.out.println("count=" + arrayCount + "row=" + row +
					 * "col=" + col);
					 */
					String secondToken = stringTokenizer2.nextToken();
					array[row][col] = Double.parseDouble(secondToken);
					arrayCount++;

					if (col == 0) {
						lat = lat + Double.parseDouble(secondToken);
					} else if (col == 1) {
						lon = lon + Double.parseDouble(secondToken);
					} else if (col == 2) {
						alt = alt + Float.parseFloat(secondToken);
					}

				}

			}
			/*
			 * //format the number DecimalFormat df = new
			 * DecimalFormat("#.####"); df.format(lat); df.format(lon);
			 * df.format(alt);
			 */

			resultMiddle = lat / tokenCount + "," + lon / tokenCount + ","
					+ alt / tokenCount;
			/*
			 * System.out.println("lan=" + lan / tokenCount);
			 * System.out.println("lon=" + lon / tokenCount);
			 * System.out.println("hight=" + hight / tokenCount);
			 */
			System.out.println("getKMLrefNo1==" + "=" + lat + "=" + lon + "="
					+ alt);
			// set the reference number
			if (lat >= 0 && lon >= 0) {
				long ref = getKMLrefNo((lat / tokenCount), (lon / tokenCount),
						(alt / tokenCount));
				if (ref != 0) {
					setReferenceNo(ref);
				} else {
					setReferenceNo(0);
				}
			} else {
				setReferenceNo(0);
			}

		} catch (Exception e) {
			e.printStackTrace();

		}
		return resultMiddle;

	}

	private String tokernizeValue(String value) {
		String valueOne = "";
		String valueTwo = "";

		StringTokenizer stringTokenizer = new StringTokenizer(value, ".");
		while (stringTokenizer.hasMoreTokens()) {
			valueOne = stringTokenizer.nextToken();
			valueTwo = stringTokenizer.nextToken();
		}
		return valueOne + valueTwo;

	}

	private long getKMLrefNo(double lat, double lon, double alt) {
		long refNo = 0;

		System.out.println("getKMLrefNo==" + "=" + lat + "=" + lon + "=" + alt);

		String latitude = tokernizeValue("" + Math.abs(lat));
		if (latitude.length() > 0) {
			String longitude = tokernizeValue("" + Math.abs(lon));

			if (longitude.length() > 0) {

				String altitude = tokernizeValue("" + Math.abs(alt));

				refNo = Long.parseLong(latitude.substring(1, 8)
						+ longitude.substring(0, 7));

				/*
				 * if (altitude.length() > 0) {
				 * 
				 * refNo = Long.parseLong(latitude.substring(1, 8) +
				 * longitude.substring(0, 7) + altitude.substring(0, 2));
				 * 
				 * 
				 * 
				 * } else { refNo = 0; }
				 */

			} else {
				refNo = 0;
			}

		} else {
			refNo = 0;
		}
		return refNo;

	}

	public void setReferenceNo(long referenceNo) {
		this.referenceNo = referenceNo;
	}

	public long getReferenceNo() {
		return referenceNo;
	}
	
	
	// Write KML
	public String writeKmlFile(String allCordiante) {
		// File createFile = null;
		String writerString = null;
		try {

			DocumentBuilderFactory docFactory = DocumentBuilderFactory
					.newInstance();
			DocumentBuilder docBuilder = docFactory.newDocumentBuilder();

			// root elements
			Document doc = docBuilder.newDocument();
			Element rootElement = doc.createElement("kml");
			doc.appendChild(rootElement);

			// placemark elements
			Element placemark = doc.createElement("Placemark");
			rootElement.appendChild(placemark);

			// name elements
			Element name = doc.createElement("name");
			name.appendChild(doc.createTextNode("Land"));
			placemark.appendChild(name);

			// Polygon elements
			Element polygon = doc.createElement("Polygon");
			placemark.appendChild(polygon);

			// extrude elements
			Element extrude = doc.createElement("extrude");
			extrude.appendChild(doc.createTextNode("1"));
			polygon.appendChild(extrude);

			// altitudeMode elements
			Element altitudeMode = doc.createElement("altitudeMode");
			altitudeMode.appendChild(doc.createTextNode("relativeToGround"));
			polygon.appendChild(altitudeMode);

			// outerBoundaryIs elements
			Element outerBoundaryIs = doc.createElement("outerBoundaryIs");
			polygon.appendChild(outerBoundaryIs);

			// LinearRing elements
			Element LinearRing = doc.createElement("LinearRing");
			outerBoundaryIs.appendChild(LinearRing);
			
			/*Element LinearRing = doc.createElement("LineString");
			outerBoundaryIs.appendChild(LinearRing);*/

			// coordinates elements
			Element coordinates = doc.createElement("coordinates");
			// ReadXMLFile readXMLFile = new ReadXMLFile();

			String resultCoordinates = allCordiante;
			String resultPoint = "";
			if (resultCoordinates != null) {
				resultPoint = getMiddlePoint(resultCoordinates);
				if (resultCoordinates.length() > 0) {
					coordinates.appendChild(doc
							.createTextNode(resultCoordinates));

				}
				System.out.println("cordinate==" + resultCoordinates);
				System.out.println("Middle==" + resultPoint);
			}

			LinearRing.appendChild(coordinates);

			// Add a point
			// placemark elements
			Element placemark2 = doc.createElement("Placemark");
			rootElement.appendChild(placemark2);

			// name elements
			Element name2 = doc.createElement("name");
			name2.appendChild(doc.createTextNode("" + getReferenceNo()));
			placemark2.appendChild(name2);

			// description elements
			Element description = doc.createElement("description");
			description.appendChild(doc.createTextNode("Middle of the Land"));
			placemark2.appendChild(description);

			// Point elements
			Element Point = doc.createElement("Point");
			placemark2.appendChild(Point);

			// coordinates elements to point
			Element coordinatesPoint = doc.createElement("coordinates");
			// String resultPoint = getMiddlePoint(resultCoordinates);

			if (resultCoordinates.length() > 0) {
				coordinatesPoint.appendChild(doc.createTextNode(resultPoint));
			}

			Point.appendChild(coordinatesPoint);

			// referenceNo elements
			Element referenceNoEle = doc.createElement("referenceNo");
			if (getReferenceNo() != 0) {
				referenceNoEle.appendChild(doc.createTextNode(""
						+ getReferenceNo()));
			}
			Point.appendChild(referenceNoEle);

			// xml to string
			DOMSource domSource = new DOMSource(doc);
			StringWriter writer = new StringWriter();
			StreamResult result = new StreamResult(writer);
			TransformerFactory tf = TransformerFactory.newInstance();
			Transformer transformer = tf.newTransformer();
			transformer.transform(domSource, result);
			writerString = writer.toString();

			Log.d("KmlWriter", "xml to String is success");

		} catch (ParserConfigurationException pce) {
			writerString = null;
			Log.d("ParserConfigurationException", pce.getMessage());

		} catch (TransformerException tfe) {
			writerString = null;
			Log.d("TransformerException", tfe.getMessage());
		}

		return writerString;
	}

}
